Skip to content

Commit c207d12

Browse files
committed
Delete content on flag approval
1 parent 9a9c82a commit c207d12

File tree

4 files changed

+70
-53
lines changed

4 files changed

+70
-53
lines changed

kitsune/flagit/models.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,20 @@ class Meta:
6565
unique_together = (("content_type", "object_id", "creator"),)
6666
ordering = ["created"]
6767
permissions = (("can_moderate", "Can moderate flagged objects"),)
68+
69+
def save(self, *args, **kwargs):
70+
owner = None
71+
if hasattr(self.content_object, "creator"):
72+
owner = self.content_object.creator
73+
elif hasattr(self.content_object, "author"):
74+
owner = self.content_object.author
75+
76+
if (
77+
int(self.status) == FlaggedObject.FLAG_ACCEPTED
78+
and owner
79+
and owner.profile.is_system_account
80+
):
81+
self.content_object.delete()
82+
self.delete()
83+
return
84+
super().save(*args, **kwargs)

kitsune/flagit/tests/test_models.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from kitsune.flagit.models import FlaggedObject
2+
from kitsune.forums.models import Post
3+
from kitsune.forums.tests import PostFactory
4+
from kitsune.sumo.tests import TestCase
5+
from kitsune.users.models import Profile
6+
from kitsune.users.tests import UserFactory
7+
8+
9+
class FlaggedObjectTests(TestCase):
10+
def setUp(self):
11+
self.user = UserFactory()
12+
self.system_user = UserFactory()
13+
self.system_user.profile.account_type = Profile.AccountType.SYSTEM
14+
self.system_user.profile.save()
15+
self.system_user_post = PostFactory(author=self.system_user)
16+
self.post = PostFactory()
17+
18+
def test_save_with_deletion(self):
19+
"""Test save that triggers deletion when conditions are met"""
20+
flag = FlaggedObject.objects.create(
21+
status=FlaggedObject.FLAG_PENDING,
22+
content_object=self.system_user_post,
23+
creator=self.user,
24+
)
25+
26+
self.assertTrue(FlaggedObject.objects.filter(id=flag.id).exists())
27+
flag.status = FlaggedObject.FLAG_ACCEPTED
28+
flag.save()
29+
self.assertFalse(FlaggedObject.objects.filter(id=flag.id).exists())
30+
self.assertFalse(Post.objects.filter(id=self.system_user_post.id).exists())
31+
32+
def test_save_with_accepted_non_system_user(self):
33+
"""Test save with accepted status but non-system user"""
34+
flag = FlaggedObject.objects.create(
35+
status=FlaggedObject.FLAG_ACCEPTED,
36+
content_object=self.post,
37+
creator=self.user,
38+
)
39+
self.assertTrue(Post.objects.filter(id=self.post.id).exists())
40+
self.assertTrue(FlaggedObject.objects.filter(id=flag.id).exists())
41+
42+
def test_save_with_system_user_non_accepted(self):
43+
"""Test save with system user but non-accepted status"""
44+
flag = FlaggedObject.objects.create(
45+
status=FlaggedObject.FLAG_PENDING,
46+
content_object=self.system_user_post,
47+
creator=self.user,
48+
)
49+
50+
self.assertTrue(Post.objects.filter(id=self.system_user_post.id).exists())
51+
self.assertTrue(FlaggedObject.objects.filter(id=flag.id).exists())

kitsune/forums/handlers.py

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from django.contrib.auth.models import User
2-
from django.contrib.contenttypes.models import ContentType
32

4-
from kitsune.flagit.models import FlaggedObject
53
from kitsune.forums.models import Post, Thread
64
from kitsune.users.handlers import UserDeletionListener
75
from kitsune.users.models import Profile
@@ -20,19 +18,4 @@ class PostListener(UserDeletionListener):
2018
"""Handles post cleanup when a user is deleted."""
2119

2220
def on_user_deletion(self, user: User) -> None:
23-
posts = Post.objects.filter(author=user)
24-
25-
post_content_type = ContentType.objects.get_for_model(Post)
26-
27-
flagged_posts = Post.objects.filter(
28-
id__in=FlaggedObject.objects.filter(
29-
content_type=post_content_type, object_id__in=posts.values_list("id", flat=True)
30-
).values_list("object_id", flat=True)
31-
)
32-
33-
for post in flagged_posts:
34-
post.delete()
35-
36-
Post.objects.filter(author=user).exclude(
37-
id__in=flagged_posts.values_list("id", flat=True)
38-
).update(author=Profile.get_sumo_bot())
21+
Post.objects.filter(author=user).update(author=Profile.get_sumo_bot())

kitsune/forums/tests/test_handlers.py

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
from django.contrib.contenttypes.models import ContentType
2-
3-
from kitsune.flagit.models import FlaggedObject
41
from kitsune.forums.handlers import PostListener, ThreadListener
5-
from kitsune.forums.models import Post, Thread
2+
from kitsune.forums.models import Thread
63
from kitsune.forums.tests import PostFactory, ThreadFactory
74
from kitsune.sumo.tests import TestCase
85
from kitsune.users.models import Profile
@@ -92,34 +89,3 @@ def test_other_users_posts_unaffected(self):
9289
post2.refresh_from_db()
9390
self.assertEqual(post1.author.username, self.sumo_bot.username)
9491
self.assertEqual(post2.author, other_user)
95-
96-
def test_flagged_posts_deletion(self):
97-
"""Test that flagged posts are deleted."""
98-
post1 = PostFactory(author=self.user)
99-
post2 = PostFactory(author=self.user)
100-
post3 = PostFactory(author=self.user)
101-
102-
post_content_type = ContentType.objects.get_for_model(Post)
103-
104-
FlaggedObject.objects.create(
105-
content_type=post_content_type,
106-
object_id=post1.id,
107-
creator=UserFactory(),
108-
reason=FlaggedObject.REASON_SPAM,
109-
)
110-
FlaggedObject.objects.create(
111-
content_type=post_content_type,
112-
object_id=post2.id,
113-
creator=UserFactory(),
114-
reason=FlaggedObject.REASON_SPAM,
115-
)
116-
117-
self.listener.on_user_deletion(self.user)
118-
119-
with self.assertRaises(Post.DoesNotExist):
120-
post1.refresh_from_db()
121-
with self.assertRaises(Post.DoesNotExist):
122-
post2.refresh_from_db()
123-
124-
post3.refresh_from_db()
125-
self.assertEqual(post3.author.username, self.sumo_bot.username)

0 commit comments

Comments
 (0)